#include "cvolume.h"
#include "cvolumemanager.h"
#include "cdock.h"
#include <buola/dbus/cproxy.h>
#include <buola/gui/cicon.h>
#include <buola/gui/cmenu.h>

namespace buola { namespace bdesktop {

CVolume::CVolume(CVolumeManager *pManager,system::PDiskDevice pVolume)
    :   mManager(pManager),
        mVolume(pVolume),
        mIcon(nullptr),
        mEjectPending(false)
{
    mDrive=mVolume->GetDrive();

    //TODO:connect to signals
    
    if(ShouldBeInDock())
    {
        PlaceInDock();
    }
}

CVolume::~CVolume()
{
}

bool CVolume::IsMounted()
{
    return mVolume->IsMounted();
}

bool CVolume::ShouldAutomount()
{
    system::EDiskUsage lFSUsage=mVolume->GetUsage();
    if(lFSUsage!=system::USAGE_FILESYSTEM) return false;
    if(mVolume->IsMounted()) return false;

    if(!mVolume->HasMedia()) return false;
    
    if(mVolume->IsRemovable()||mDrive->IsDetachable()) return true;
    
    return false;
}

void CVolume::Mount()
{
    std::vector<std::string> lOptions;
    mVolume->Mount(lOptions);
}

void CVolume::Unmount()
{
    mVolume->Unmount();
}

void CVolume::Eject(bool pUnmount)
{
    if(mVolume->IsMounted())
    {
        if(pUnmount)
        {
            Unmount();
            mEjectPending=true;
        }
        return;
    }

    mDrive->Eject();
    mEjectPending=false;
}

bool CVolume::ShouldBeInDock()
{
    return (mVolume->IsRemovable()||mDrive->IsDetachable())&&(mVolume->IsMounted()||mVolume->IsBlank());
}

void CVolume::PlaceInDock()
{
    PImage lImage=gui::CIcon::Get(mVolume->GetIconName())->GetImage(128);
    mIcon=new CImageIcon(lImage);
    mIcon->SetText(mVolume->GetLabel());
    mIcon->sClicked.Connect(&CVolume::OnIconClicked,this,_1);
    mManager->GetDock()->AddIcon(mIcon,CDock::GROUP_MEDIA);
}

void CVolume::RemoveFromDock()
{
    assert(mIcon);
    mManager->GetDock()->RemoveIcon(mIcon);
    delete mIcon;
    mIcon=nullptr;
}

bool CVolume::ShouldBeInPlacesMenu()
{
    return mVolume->IsMounted();
}

void CVolume::AddToPlacesMenu(gui::PMenu pMenu)
{
    std::wstring lLabel=mVolume->GetLabel();
    std::string lMountPoint=mVolume->GetMountPoint();
    
    if(lLabel.empty())
    {
        if(lMountPoint=="/")
        {
            lLabel=L"Filesystem";
        }
        else
        {
            lLabel=L"unnamed";
        }
    }

    std::string lComment=lMountPoint + "(";
    //\todo
    // << FFileSize(mVolume->GetAvailable()) << " free)";

    pMenu->Add(gui::new_menu_item(lLabel,mVolume->GetIconName(),nullptr,decode(lComment)))->
            eTriggered.Connect(&CVolume::LaunchBrowser,this);
}

void CVolume::LaunchBrowser()
{
    if(mDrive->GetDriveType()==system::DRIVE_OPTICAL&&mVolume->IsBlank())
    {
        dbus::CProxy lProxy(dbus::get_session_bus(),"org.buola.Burner","/org/buola/Burner");
        lProxy.CallIgnore("org.buola.Burner","OpenDevice",mDrive->GetDeviceName());
    }
    else
    {
        dbus::CProxy lProxy(dbus::get_session_bus(),"org.buola.Browser","/org/buola/Browser");
        lProxy.CallIgnore("org.buola.Browser","NewWindow",mVolume->GetMountPoint());
    }
}

void CVolume::OnIconClicked(gui::CMouseEvent *pE)
{
    if(pE->mButton==gui::MOUSE_LEFT)
        LaunchBrowser();
}

void CVolume::OnPropertyChanged(EObject pObj,const std::string &pProp)
{
    if(pObj==VOLUME)
    {
//        msg_debug<5>() << "property changed in volume"  << pProp << " to "
//            << mVolume->GetDevice()->GetStringProperty(pProp) << "\n";
/*
        if(pProp=="volume.is_mounted")
        {
            if(mVolume->IsMounted())
            {
                if(!mIcon&&ShouldBeInDock())
                    PlaceInDock();
            }
            else
            {
                if(mIcon)
                    RemoveFromDock();
                if(mEjectPending)
                    Eject(false);
            }
        }*/
    }
    
}

void CVolume::OnCondition(EObject pObj,const std::string &pName,const std::string &pDetail)
{
    if(pObj==DRIVE)
    {
        if(pName=="EjectPressed")
        {
            Eject(true);
        }
    }
}

/*namespace bdesktop*/ } /*namespace buola*/ }
